* use container for garmin_fs ilinks.
and leave memory management up to the copy on write container.
* make gmsd const for read only usage.
this prevents the possiblity of detachment of the ilinks list.
* incorporate some variables and functions into garmin_fs_t
* unify garmin category conversions.
* fiddle with test time zone sensitivity.
* add utc option for garmin_txt reader.
* correct sign of adjustment
* update garmin_txt includes.
static void
garmin_fs_garmin_after_read(const GPS_PWay way, Waypoint* wpt, const int protoid)
{
- garmin_fs_t* gmsd = garmin_fs_alloc(protoid);
+ auto* gmsd = new garmin_fs_t(protoid);
wpt->fs.FsChainAdd(gmsd);
/* nothing happens until gmsd is allocated some lines above */
static void
garmin_fs_garmin_before_write(const Waypoint* wpt, GPS_PWay way, const int protoid)
{
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
(void)protoid; // unused for now.
#include "inifile.h" // for inifile_readstr
-#define MYNAME "garmin_fs"
-
-garmin_fs_t*
-garmin_fs_alloc(const int protocol)
-{
- auto* result = new garmin_fs_t;
-
- result->protocol = protocol;
-
- return result;
-}
-
-garmin_fs_t* garmin_fs_t::clone() const
+std::optional<uint16_t>
+garmin_fs_t::convert_category(const QString& category_name)
{
- auto* copy = new garmin_fs_t(*this);
+ std::optional<uint16_t> category;
- /* do not deep copy interlinks, only increment the reference counter */
- if (ilinks != nullptr) {
- ilinks->ref_count++;
- }
-
-#ifdef GMSD_EXPERIMENTAL
- memcopy(subclass, other.subclass, sizeof(subclass));
-#endif
-
- return copy;
-}
-
-garmin_fs_t::~garmin_fs_t()
-{
- garmin_ilink_t* links;
- if ((links = ilinks) != nullptr) {
- links->ref_count--;
- if (links->ref_count <= 0) {
- while (links != nullptr) {
- garmin_ilink_t* tmp = links;
- links = links->next;
- xfree(tmp);
- }
- }
- }
-}
-
-bool
-garmin_fs_convert_category(const QString& category_name, uint16_t* category)
-{
// Is the name "Category" followed by a number? Use that number.
if (category_name.startsWith(u"Category ", Qt::CaseInsensitive)) {
bool ok;
int i = category_name.mid(9).toInt(&ok);
if (ok && (i >= 1) && (i <= 16)) {
- *category = (1 << --i);
- return true;
+ category = (1 << --i);
+ return category;
}
}
if (global_opts.inifile != nullptr) {
// Do we have a gpsbabel.ini that maps category names to category #'s?
for (int i = 0; i < 16; i++) {
QString key = QString::number(i + 1);
- QString c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key);
+ QString c = inifile_readstr(global_opts.inifile, kGmsdSectionCategories, key);
if (c.compare(category_name, Qt::CaseInsensitive) == 0) {
- *category = (1 << i);
- return true;
+ category = (1 << i);
+ return category;
}
}
}
- return false;
+ return category;
}
-bool
-garmin_fs_merge_category(const QString& category_name, Waypoint* waypt)
+QStringList
+garmin_fs_t::print_categories(uint16_t categories)
{
- uint16_t cat;
+ QStringList categoryList;
- // Attempt to get a textual category name to a category number.
- if (!garmin_fs_convert_category(category_name, &cat)) {
- return false;
+ if (categories == 0) {
+ return categoryList;
}
- garmin_fs_t* gmsd = garmin_fs_t::find(waypt);
- cat = cat | (garmin_fs_t::get_category(gmsd, 0));
+ for (int i = 0; i < 16; i++) {
+ if ((categories & 1) != 0) {
+ QString c;
+ if (global_opts.inifile != nullptr) {
+ QString key = QString::number(i + 1);
+ c = inifile_readstr(global_opts.inifile, kGmsdSectionCategories, key);
+ }
- if (gmsd == nullptr) {
- gmsd = garmin_fs_alloc(-1);
- waypt->fs.FsChainAdd(gmsd);
+ if (c.isNull()) {
+ categoryList << QString::asprintf("Category %d", i+1);
+ }
+// *fout << QString::asprintf("%s", gps_categories[i]);
+ else {
+ categoryList << c;
+ }
+
+ }
+ categories = categories >> 1;
}
- garmin_fs_t::set_category(gmsd, cat);
- return true;
+ return categoryList;
}
#define GARMIN_FS_H
#include <cstdint> // for int32_t, int16_t, uint16_t
+#include <optional> // for optional
+#include <QList> // for QList
#include <QString> // for QString
#include "defs.h"
*/
struct garmin_ilink_t {
- int ref_count;
- double lat, lon, alt;
- garmin_ilink_t* next;
+ double lat;
+ double lon;
+ double alt;
};
struct garmin_fs_flags_t {
class garmin_fs_t : public FormatSpecificData {
public:
+ /* Data Members */
+
garmin_fs_flags_t flags;
int protocol{0}; /* ... used by device (-1 is MapSource) */
QString email; /* email address */
unsigned int duration; /* expected travel time to next route point, in seconds, only when auto-routed */
- garmin_ilink_t* ilinks{nullptr};
+ QList<garmin_ilink_t> ilinks;
#ifdef GMSD_EXPERIMENTAL
char subclass[22]{};
#endif
-public:
+ /* Special Member Functions */
+
garmin_fs_t() : FormatSpecificData(kFsGmsd) {}
-private:
- garmin_fs_t(const garmin_fs_t& other) = default;
-public:
- garmin_fs_t& operator=(const garmin_fs_t& rhs) = delete; /* not implemented */
- garmin_fs_t(garmin_fs_t&&) = delete; /* not implemented */
- garmin_fs_t& operator=(garmin_fs_t&&) = delete; /* not implemented */
- ~garmin_fs_t() override;
+ explicit garmin_fs_t(int p) : garmin_fs_t() {protocol = p;}
+
+ /* Member Functions */
+
+ garmin_fs_t* clone() const override
+ {
+ return new garmin_fs_t(*this);
+ }
- garmin_fs_t* clone() const override;
static garmin_fs_t* find(const Waypoint* wpt) {
return reinterpret_cast<garmin_fs_t*>(wpt->fs.FsChainFind(kFsGmsd));
}
+ static std::optional<uint16_t> convert_category(const QString& category_name);
+ static QStringList print_categories(uint16_t categories);
+
#define GEN_GMSD_METHODS(field) \
static bool has_##field(const garmin_fs_t* gmsd) \
{ \
GEN_GMSD_STR_METHODS(email)
#undef GEN_GMSD_STR_METHODS
-};
-
-garmin_fs_t* garmin_fs_alloc(int protocol);
-void garmin_fs_destroy(void* fs);
-void garmin_fs_copy(void** dest, const void* src);
-
-/* ..convert_category: returns true=OK; false=Unable to convert category */
-bool garmin_fs_convert_category(const QString& category_name, uint16_t* category);
-/* ..merge_category: returns true=OK; false=Unable to convert category */
-bool garmin_fs_merge_category(const QString& category_name, Waypoint* waypt);
-
-#define GMSD_SECTION_CATEGORIES "Garmin Categories"
+private:
+ /* Constants */
+ static constexpr char kGmsdSectionCategories[] = "Garmin Categories";
+};
#endif
#include "defs.h"
#include "formspec.h" // for FormatSpecificDataList
-#include "garmin_fs.h" // for garmin_fs_t, garmin_fs_alloc
+#include "garmin_fs.h" // for garmin_fs_t
#include "gbfile.h" // for gbfputint32, gbfgetint32, gbfgetint16, gbfputint16, gbfgetc, gbfputc, gbfread, gbftell, gbfwrite, gbfseek, gbfclose, gbfopen_le, gbfgetuint16, gbsize_t, gbfile
#include "jeeps/gpsmath.h" // for GPS_Math_Deg_To_Semi, GPS_Math_Semi_To_Deg
}
garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
if (gmsd == nullptr) {
- gmsd = garmin_fs_alloc(-1);
+ gmsd = new garmin_fs_t(-1);
wpt->fs.FsChainAdd(gmsd);
}
return gmsd;
res = 23; /* bounds, ... of tag 0x80008 */
foreach (Waypoint* wpt, data->waypt_list) {
- garmin_fs_t* gmsd;
+ const garmin_fs_t* gmsd;
res += 12; /* tag/sz/sub-sz */
res += 19; /* poi fixed size */
#include <cstdlib> // for abs
#include <cstring> // for strstr, strlen
#include <ctime> // for time_t, gmtime, localtime, strftime
+#include <optional> // for optional
#include <utility> // for pair, make_pair
#include <QByteArray> // for QByteArray
#include "csv_util.h" // for csv_linesplit
#include "formspec.h" // for FormatSpecificDataList
-#include "garmin_fs.h" // for garmin_fs_t, garmin_fs_alloc, garmin_fs_convert_category, GMSD_SECTION_CATEGORIES
+#include "garmin_fs.h" // for garmin_fs_t
#include "garmin_tables.h" // for gt_display_modes_e, gt_find_desc_from_icon_number, gt_find_icon_number_from_desc, gt_get_mps_grid_longname, gt_lookup_datum_index, gt_lookup_grid_type, GDB, gt_get_icao_cc, gt_get_icao_country, gt_get_mps_datum_name, gt_waypt_class_names, GT_DISPLAY_MODE...
-#include "inifile.h" // for inifile_readstr
#include "jeeps/gpsmath.h" // for GPS_Math_Known_Datum_To_UTM_EN, GPS_Math_WGS84_To_Known_Datum_M, GPS_Math_WGS84_To_Swiss_EN, GPS_Math_WGS84_To_UKOSMap_M
#include "src/core/datetime.h" // for DateTime
#include "src/core/logging.h" // for Fatal
static void
enum_waypt_cb(const Waypoint* wpt)
{
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
int wpt_class = garmin_fs_t::get_wpt_class(gmsd, 0);
if (wpt_class < 0x80) {
if (gtxt_flags.enum_waypoints) { /* enumerate only */
static void
print_categories(uint16_t categories)
{
- if (categories == 0) {
- return;
- }
-
- int count = 0;
- for (int i = 0; i < 16; i++) {
- if ((categories & 1) != 0) {
- QString c;
- if (global_opts.inifile != nullptr) {
- QString key = QString::number(i + 1);
- c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key);
- }
-
- *fout << QString::asprintf("%s", (count++ > 0) ? "," : "");
- if (c.isNull()) {
- *fout << QString::asprintf("Category %d", i+1);
- }
-// *fout << QString::asprintf("%s", gps_categories[i]);
- else {
- *fout << c;
- }
-
- }
- categories = categories >> 1;
+ const QStringList categoryList = garmin_fs_t::print_categories(categories);
+ if (!categoryList.isEmpty()) {
+ *fout << categoryList.join(',');
}
}
{
const char* wpt_type;
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
int i = garmin_fs_t::get_display(gmsd, 0);
if (i > GT_DISPLAY_MODE_MAX) {
* %%% global callbacks called by gpsbabel main process %%% *
*******************************************************************************/
+static void
+garmin_txt_utc_option()
+{
+ if (opt_utc != nullptr) {
+ if (case_ignore_strcmp(opt_utc, "utc") == 0) {
+ utc_offs = 0;
+ } else {
+ utc_offs = xstrtoi(opt_utc, nullptr, 10);
+ }
+ utc_offs *= (60 * 60);
+ gtxt_flags.utc = 1;
+ }
+}
+
+static void
+garmin_txt_adjust_time(QDateTime& dt)
+{
+ if (gtxt_flags.utc) {
+ dt = dt.toUTC().addSecs(dt.offsetFromUtc() - utc_offs);
+ }
+}
+
static void
garmin_txt_wr_init(const QString& fname)
{
datum_index = gt_lookup_datum_index(datum_str, MYNAME);
}
- if (opt_utc != nullptr) {
- if (case_ignore_strcmp(opt_utc, "utc") == 0) {
- utc_offs = 0;
- } else {
- utc_offs = xstrtoi(opt_utc, nullptr, 10);
- }
- utc_offs *= (60 * 60);
- gtxt_flags.utc = 1;
- }
+ garmin_txt_utc_option();
}
static void
q += "yyyy";
continue;
case 'H':
- q += "hh";
+ q += "HH";
continue;
case 'M':
q += "mm";
case 'F':
q += "yyyy-MM-dd";
continue;
+ case 'p':
+ q += "AP";
+ continue;
default:
- q += s[i+1];
+ warning(MYNAME ": omitting unknown strptime conversion \"%%%c\" in \"%s\"\n", s[i], s);
break;
}
}
for (const auto& catstring : catstrings) {
QString cin = catstring.trimmed();
if (!cin.isEmpty()) {
- uint16_t val;
- if (!garmin_fs_convert_category(cin, &val)) {
+ if (std::optional<uint16_t> cat = garmin_fs_t::convert_category(cin); !cat.has_value()) {
warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", qPrintable(cin), current_line);
} else {
- res = res | val;
+ res = res | *cat;
}
}
}
bind_fields(waypt_header);
auto* wpt = new Waypoint;
- garmin_fs_t* gmsd = garmin_fs_alloc(-1);
+ auto* gmsd = new garmin_fs_t(-1);
wpt->fs.FsChainAdd(gmsd);
for (const auto& str : lineparts) {
break;
case 16:
if (QDateTime dt = parse_date_and_time(str); dt.isValid()) {
+ garmin_txt_adjust_time(dt);
wpt->SetCreationTime(dt);
}
break;
break;
case 2:
if (QDateTime dt = parse_date_and_time(str); dt.isValid()) {
+ garmin_txt_adjust_time(dt);
wpt->SetCreationTime(dt);
}
break;
grid_index = (grid_type) -1;
init_date_and_time_format();
+ garmin_txt_utc_option();
}
static void
#include "defs.h" // for Waypoint, warning, route_head, fatal, UrlLink, bounds, UrlList, unknown_alt, xfree, waypt_add_to_bounds, waypt_init_bounds, xstrtoi, route_add_wpt, route_disp_all, waypt_bounds_valid, xmalloc, gb_color, WaypointList, find_wa...
#include "formspec.h" // for FormatSpecificDataList
-#include "garmin_fs.h" // for garmin_fs_t, garmin_ilink_t, garmin_fs_alloc
+#include "garmin_fs.h" // for garmin_fs_t, garmin_ilink_t
#include "garmin_tables.h" // for gt_waypt_class_map_point, gt_color_index_by_rgb, gt_color_value, gt_waypt_classes_e, gt_find_desc_from_icon_number, gt_find_icon_number_from_desc, gt_gdb_display_mode_symbol, gt_get_icao_country, gt_waypt_class_user_waypoint, GDB, gt_display_mode_symbol
#include "gbfile.h" // for gbfgetint32, gbfputint32, gbfgetc, gbfread, gbfwrite, gbfgetdbl, gbfputc, gbfgetcstr, gbfclose, gbfgetnativecstr, gbfopen_le, gbfputint16, gbfile, gbfcopyfrom, gbfputcstr, gbfrewind, gbfseek, gbftell, gbfgetcstr_old, gbfgetint16, gbfgetuint32, gbfputdbl
#include "grtcirc.h" // for RAD, gcdist, radtometers
waypt_ct++;
res = new Waypoint;
- gmsd = garmin_fs_alloc(-1);
+ gmsd = new garmin_fs_t(-1);
res->fs.FsChainAdd(gmsd);
res->shortname = fread_cstr();
wpt_class = (gt_waypt_classes_e) FREAD_i32;
}
int links = FREAD_i32;
- garmin_ilink_t* il_anchor = nullptr;
- garmin_ilink_t* il_root = nullptr;
+ QList<garmin_ilink_t> il_list;
#if GDB_DEBUG
DBG(GDB_DBG_RTE, links)
printf(MYNAME "-rte_pt \"%s\" (%d): %d interlink step(s)\n",
qPrintable(wpt->shortname), wpt_class, links);
#endif
for (int j = 0; j < links; j++) {
- auto* il_step = (garmin_ilink_t*) xmalloc(sizeof(garmin_ilink_t));
+ garmin_ilink_t il_step;
- il_step->ref_count = 1;
-
- il_step->lat = FREAD_LATLON;
- il_step->lon = FREAD_LATLON;
+ il_step.lat = FREAD_LATLON;
+ il_step.lon = FREAD_LATLON;
if (FREAD_C == 1) {
- il_step->alt = FREAD_DBL;
+ il_step.alt = FREAD_DBL;
} else {
- il_step->alt = unknown_alt;
+ il_step.alt = unknown_alt;
}
if (j == 0) {
- wpt->latitude = il_step->lat;
- wpt->longitude = il_step->lon;
- wpt->altitude = il_step->alt;
+ wpt->latitude = il_step.lat;
+ wpt->longitude = il_step.lon;
+ wpt->altitude = il_step.alt;
}
- il_step->next = nullptr;
- if (il_anchor == nullptr) {
- il_root = il_step;
- } else {
- il_anchor->next = il_step;
- }
- il_anchor = il_step;
+ il_list.append(il_step);
#if GDB_DEBUG
DBG(GDB_DBG_RTEe, true) {
printf(MYNAME "-rte_il \"%s\" (%d of %d): %c%0.6f %c%0.6f\n",
qPrintable(wpt->shortname), j + 1, links,
- il_step->lat < 0 ? 'S' : 'N', il_step->lat,
- il_step->lon < 0 ? 'W' : 'E', il_step->lon);
+ il_step.lat < 0 ? 'S' : 'N', il_step.lat,
+ il_step.lon < 0 ? 'W' : 'E', il_step.lon);
}
#endif
}
if (wpt != nullptr) {
garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
if (gmsd == nullptr) {
- gmsd = garmin_fs_alloc(-1);
+ gmsd = new garmin_fs_t(-1);
wpt->fs.FsChainAdd(gmsd);
}
garmin_fs_t::set_wpt_class(gmsd, wpt_class);
- gmsd->ilinks = il_root;
- il_root = nullptr;
+ gmsd->ilinks = il_list;
}
- while (il_root) {
- garmin_ilink_t* il = il_root;
- il_root = il_root->next;
- xfree(il);
- }
} /* ENDFOR: for (i = 0; i < points; i++) */
/* VERSION DEPENDENT CODE */
void
GdbFormat::write_waypoint(
- const Waypoint* wpt, const QString& shortname, garmin_fs_t* gmsd,
+ const Waypoint* wpt, const QString& shortname, const garmin_fs_t* gmsd,
const int icon, const int display)
{
char zbuf[32], ffbuf[32];
fatal(MYNAME ": Sorry, that should never happen!!!\n");
}
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
/* extra_data may contain a modified shortname */
gdb_write_cstr((wpt->extra_data) ? *static_cast<QString*>(wpt->extra_data) : wpt->shortname);
fout = ftmp;
/* prepare the waypoint */
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
int wpt_class = garmin_fs_t::get_wpt_class(gmsd, -1);
if (wpt_class == -1) {
void reset_short_handle(const char* defname);
void write_header();
static void gdb_check_waypt(Waypoint* wpt);
- void write_waypoint(const Waypoint* wpt, const QString& shortname, garmin_fs_t* gmsd, int icon, int display);
+ void write_waypoint(const Waypoint* wpt, const QString& shortname, const garmin_fs_t* gmsd, int icon, int display);
static void route_compute_bounds(const route_head* rte, bounds* bounds);
void route_write_bounds(bounds* bounds) const;
void write_route(const route_head* rte, const QString& rte_name);
#include <QtGlobal> // for qAsConst, QAddConst<>::Type
#include "defs.h"
-#include "garmin_fs.h" // for garmin_fs_t, garmin_ilink_t, garmin_fs_alloc, garmin_fs_merge_category
+#include "garmin_fs.h" // for garmin_fs_t, garmin_ilink_t
#include "garmin_tables.h" // for gt_color_index_by_rgb, gt_color_name, gt_color_value_by_name
#include "geocache.h" // for Geocache, Geocache::UtfSt...
#include "mkshort.h" // for MakeShort
{
garmin_fs_t* gmsd = garmin_fs_t::find(waypt);
if (gmsd == nullptr) {
- gmsd = garmin_fs_alloc(-1);
+ gmsd = new garmin_fs_t(-1);
waypt->fs.FsChainAdd(gmsd);
}
}
break;
case tag_type::garmin_wpt_category:
- if (!garmin_fs_merge_category(text, waypt)) {
+ if (auto cat = garmin_fs_t::convert_category(text); cat.has_value()) {
+ cat = *cat | (garmin_fs_t::get_category(gmsd, 0));
+ garmin_fs_t::set_category(gmsd, *cat);
+ } else {
// There's nothing a user can really do about this (well, they could
// create a gpsbabel.ini that mapped them to garmin category numbers
// but that feature is so obscure and used in so few outputs that
// Although not required by the schema we assume that gpxx:RoutePointExtension must be a child of gpx:rtept.
// Although not required by the schema we assume that gpxx:TrackPointExtension must be a child of gpx:trkpt.
// Although not required by the schema we assume that gpxtpx:TrackPointExtension must be a child of gpx:trkpt.
- garmin_fs_t* gmsd = garmin_fs_t::find(waypointp);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(waypointp);
switch (point_type) {
case gpxpt_waypoint:
writer->stackOptionalStartElement(QStringLiteral("gpxx:WaypointExtension"));
if (garmin_fs_t::has_category(gmsd)) {
uint16_t cx = gmsd->category;
writer->stackStartElement(QStringLiteral("gpxx:Categories"));
- for (int i = 0; i < 16; i++) {
- if (cx & 1) {
- writer->stackTextElement(QStringLiteral("gpxx:Category"), QStringLiteral("Category %1").arg(i+1));
- }
- cx = cx >> 1;
+ const QStringList categoryList = garmin_fs_t::print_categories(cx);
+ for (const auto& text : categoryList) {
+ writer->stackTextElement(QStringLiteral("gpxx:Category"), text);
}
writer->stackEndElement(); // gpxx:Categories
}
writer->stackEndElement(); // gpxx:WaypointExtension
break;
case gpxpt_route:
- if (gmsd != nullptr && gmsd->ilinks != nullptr) {
+ if (gmsd != nullptr && !gmsd->ilinks.isEmpty()) {
writer->stackOptionalStartElement(QStringLiteral("gpxx:RoutePointExtension"));
- garmin_ilink_t* link = gmsd->ilinks;
- garmin_ilink_t* prior = nullptr; // GDB files sometime contain repeated point; omit them
- while (link != nullptr) {
- if (prior == nullptr || prior->lat != link->lat || prior->lon != link->lon) {
+ double prior_lat; // GDB files sometime contain repeated point; omit them
+ double prior_lon;
+ bool first = true;
+ for (const auto& link : gmsd->ilinks) {
+ if (first || (prior_lat != link.lat) || (prior_lon != link.lon)) {
writer->stackStartElement(QStringLiteral("gpxx:rpt"));
- writer->stackAttribute(QStringLiteral("lat"), toString(link->lat));
- writer->stackAttribute(QStringLiteral("lon"), toString(link->lon));
+ writer->stackAttribute(QStringLiteral("lat"), toString(link.lat));
+ writer->stackAttribute(QStringLiteral("lon"), toString(link.lon));
writer->stackEndElement(); // "gpxx:rpt"
+ prior_lat = link.lat;
+ prior_lon = link.lon;
+ first = false;
}
- prior = link;
- link = link->next;
}
writer->stackEndElement(); // gpxx:RoutePointExtension
}
#include "defs.h"
#include "random.h"
#include "formspec.h" // for FormatSpecificDataList
-#include "garmin_fs.h" // for garmin_fs_t, GMSD_SET, garmin_fs_flags_t, garmin_fs_alloc
+#include "garmin_fs.h" // for garmin_fs_t, GMSD_SET, garmin_fs_flags_t
#include "src/core/datetime.h" // for DateTime
RandomFormat::random_generate_wpt(int i, const QDateTime& time, const Waypoint* prev)
{
auto* wpt = new Waypoint;
- garmin_fs_t* gmsd = garmin_fs_alloc(-1);
+ auto* gmsd = new garmin_fs_t(-1);
wpt->fs.FsChainAdd(gmsd);
do {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx version="1.1" creator="GPSBabel - https://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1">
+ <metadata>
+ <time>1970-01-01T00:00:00Z</time>
+ <bounds minlat="39.973869717" minlon="-105.498962400" maxlat="40.003967283" maxlon="-105.465850367"/>
+ </metadata>
+ <wpt lat="39.973869717" lon="-105.465850367">
+ <time>2013-03-09T20:45:12Z</time>
+ <name>Hwy 119</name>
+ <cmt>The Diagonal</cmt>
+ <desc>The Diagonal</desc>
+ <sym>Flag, Blue</sym>
+ <extensions>
+ <gpxx:WaypointExtension>
+ <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
+ <gpxx:Categories>
+ <gpxx:Category>Slow food</gpxx:Category>
+ <gpxx:Category>Category 11</gpxx:Category>
+ </gpxx:Categories>
+ </gpxx:WaypointExtension>
+ </extensions>
+ </wpt>
+ <wpt lat="40.003967283" lon="-105.498962400">
+ <time>2013-03-09T20:45:02Z</time>
+ <name>Hwy 72</name>
+ <cmt>The Peak to Peak</cmt>
+ <desc>The Peak to Peak</desc>
+ <sym>Flag, Blue</sym>
+ <extensions>
+ <gpxx:WaypointExtension>
+ <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
+ </gpxx:WaypointExtension>
+ </extensions>
+ </wpt>
+</gpx>
--- /dev/null
+Grid Lat/Lon hddd°mm.mmm'\r
+Datum WGS 84\r
+\r
+Header Name Description Type Position Altitude Depth Proximity Temperature Display Mode Color Symbol Facility City State Country Date Modified Link Categories\r
+\r
+Waypoint Hwy 119 The Diagonal User Waypoint N39 58.432183 W105 27.951022 Symbol & Name Unknown Flag, Blue 09.03.2013 13:45:12 PM Slow food,Category 11\r
+Waypoint Hwy 72 The Peak to Peak User Waypoint N40 00.238037 W105 29.937744 Symbol & Name Unknown Flag, Blue 09.03.2013 13:45:02 PM \r
gpsbabel -i gpx -f ${REFERENCE}/gpxpassthrough11.gpx -o gpx -F ${TMPDIR}/gpxpassthrough11~gpx.gpx
compare ${REFERENCE}/gpxpassthrough11~gpx.gpx ${TMPDIR}/gpxpassthrough11~gpx.gpx
+# garmin specific categories
+gpsbabel -p gpsbabel-sample.ini -i gpx -f ${REFERENCE}/garmincategories.gpx -o garmin_txt,utc=-7 -F ${TMPDIR}/garmincategories~gpx.txt
+compare ${REFERENCE}/garmincategories.txt ${TMPDIR}/garmincategories~gpx.txt
+
+gpsbabel -p gpsbabel-sample.ini -i garmin_txt,utc=-7 -f ${REFERENCE}/garmincategories.txt -o gpx,garminextensions -F ${TMPDIR}/garmincategories~txt.gpx
+compare ${REFERENCE}/garmincategories.gpx ${TMPDIR}/garmincategories~txt.gpx
+
if [ -z "${VALGRIND}" ]; then
set -e
if command -v xmllint > /dev/null;
#include "defs.h"
#include "csv_util.h" // for csv_linesplit, human_to_dec
#include "formspec.h" // for FormatSpecificDataList
-#include "garmin_fs.h" // for garmin_fs_flags_t, garmin_fs_t, GMSD_GET, GMSD_HAS, GMSD_SETQSTR, GMSD_FIND, garmin_fs_alloc
+#include "garmin_fs.h" // for garmin_fs_t
#include "garmin_tables.h" // for gt_lookup_datum_index, gt_get_mps_grid_longname, gt_lookup_grid_type
#include "geocache.h" // for Geocache, Geocache::status_t, Geoc...
#include "jeeps/gpsmath.h" // for GPS_Math_UKOSMap_To_WGS84_M, GPS_Math_EN_To_UKOSNG_Map, GPS_Math_Known_Datum_To_UTM_EN, GPS_Math_Known_Datum_To_WGS84_M, GPS_Math_Swiss_EN_To_WGS84, GPS_Math_UTM_EN_To_Known_Datum, GPS_Math_WGS84_To_Known_Datum_M, GPS_Math_WGS84_To_Swiss_EN, GPS_Math_WGS...
case fld_garmin_facility:
gmsd = garmin_fs_t::find(wpt);
if (! gmsd) {
- gmsd = garmin_fs_alloc(-1);
+ gmsd = new garmin_fs_t(-1);
wpt->fs.FsChainAdd(gmsd);
}
switch (unicsv_fields_tab[column]) {
UnicsvFormat::unicsv_waypt_enum_cb(const Waypoint* wpt)
{
const QString& shortname = wpt->shortname;
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
if (!shortname.isEmpty()) {
unicsv_outp_flags[fld_shortname] = true;
unicsv_waypt_ct++;
QString shortname = wpt->shortname;
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
if (unicsv_datum_idx == kDautmWGS84) {
lat = wpt->latitude;
}
if (okay == 0) {
- fatal("Invalid character \"%c\" in date format!", *cin);
+ fatal("Invalid character \"%c\" in date format \"%s\"!\n", *cin, human_datef);
}
}
QString rv(result);
}
if (okay == 0) {
- fatal("Invalid character \"%c\" in time format!", *cin);
+ fatal("Invalid character \"%c\" in time format \"%s\"!\n", *cin, human_timef);
}
}
QString rv(result);
waypt_distance_ex(const Waypoint* A, const Waypoint* B)
{
double res = 0;
- garmin_fs_t* gmsd;
if ((A == nullptr) || (B == nullptr)) {
return 0;
}
- if ((gmsd = garmin_fs_t::find(A)) && (gmsd->ilinks != nullptr)) {
- garmin_ilink_t* link = gmsd->ilinks;
-
- res = gcgeodist(A->latitude, A->longitude, link->lat, link->lon);
- while (link->next != nullptr) {
- garmin_ilink_t* prev = link;
- link = link->next;
- res += gcgeodist(prev->lat, prev->lon, link->lat, link->lon);
+ if (const garmin_fs_t* gmsd = garmin_fs_t::find(A); (gmsd != nullptr) && (!gmsd->ilinks.isEmpty())) {
+ auto prev_lat = A->latitude;
+ auto prev_lon = A->longitude;
+ for (const auto& link : gmsd->ilinks) {
+ res += gcgeodist(prev_lat, prev_lon, link.lat, link.lon);
+ prev_lat = link.lat;
+ prev_lon = link.lon;
}
- res += gcgeodist(link->lat, link->lon, B->latitude, B->longitude);
+ res += gcgeodist(gmsd->ilinks.last().lat, gmsd->ilinks.last().lon, B->latitude, B->longitude);
} else {
res = gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude);
}
#include "defs.h"
#include "csv_util.h" // for csv_stringtrim, dec_to_human, csv_stringclean, human_to_dec, ddmmdir_to_degrees, dec_to_intdeg, decdir_to_dec, intdeg_to_dec, csv_linesplit
#include "formspec.h" // for FormatSpecificDataList
-#include "garmin_fs.h" // for garmin_fs_t, garmin_fs_alloc
+#include "garmin_fs.h" // for garmin_fs_t
#include "geocache.h" // for Geocache, Geocache::status_t, Geoc...
#include "grtcirc.h" // for RAD, gcdist, radtometers
#include "jeeps/gpsmath.h" // for GPS_Math_WGS84_To_UTM_EN, GPS_Lookup_Datum_Index, GPS_Math_Known_Datum_To_WGS84_M, GPS_Math_UTM_EN_To_Known_Datum, GPS_Math_WGS84_To_Known_Datum_M, GPS_Math_WGS84_To_UKOSMap_M
{
garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
if (gmsd == nullptr) {
- gmsd = garmin_fs_alloc(-1);
+ gmsd = new garmin_fs_t(-1);
wpt->fs.FsChainAdd(gmsd);
}
return gmsd;
break;
/* GMSD ************************************************************/
case XcsvStyle::XT_COUNTRY: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_country(gmsd, "")));
}
break;
case XcsvStyle::XT_STATE: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_state(gmsd, "")));
}
break;
case XcsvStyle::XT_CITY: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_city(gmsd, "")));
}
break;
case XcsvStyle::XT_POSTAL_CODE: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_postal_code(gmsd, "")));
}
break;
case XcsvStyle::XT_STREET_ADDR: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_addr(gmsd, "")));
}
break;
case XcsvStyle::XT_PHONE_NR: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_phone_nr(gmsd, "")));
}
break;
case XcsvStyle::XT_FACILITY: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_facility(gmsd, "")));
}
break;
case XcsvStyle::XT_EMAIL: {
- garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
+ const garmin_fs_t* gmsd = garmin_fs_t::find(wpt);
buff = QString::asprintf(fmp.printfc.constData(), CSTR(garmin_fs_t::get_email(gmsd, "")));
}
break;